home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / c_news / 18 / dl / dl.cpp < prev    next >
C/C++ Source or Header  |  1989-12-17  |  18KB  |  506 lines

  1. //////////////////////////////////////////////////////////
  2. //                                                      //
  3. //           ******************************             //
  4. //           ****  Browning's Classes  ****             //
  5. //           ******************************             //
  6. //                                                      //
  7. //                  Class DL_3.Cpp                      //
  8. //                                                      //
  9. //       Public Domain           Roy G. Browning        //
  10. //       December 1989           The Fulcrum's Edge     //
  11. //                                                      //
  12. //       Zortech C/C++           version 2.01           //
  13. //                                                      //
  14. //       Ztc -o -mti DL_3                               //
  15. //                                                      //
  16. //       Initiated               05-01-1989             //
  17. //////////////////////////////////////////////////////////
  18.  
  19. //////////////////////////////////////////////////////////
  20. //                                                      //
  21. //                   Charity Request                    //
  22. //                                                      //
  23. //       If benefit is derived in any fashion from      //
  24. //       this public code it is requested that a        //
  25. //       donation be made to a children's charity       //
  26. //       if sufficient funds are available.             //
  27. //                                                      //
  28. //////////////////////////////////////////////////////////
  29.  
  30. //////////////////////////////////////////////////////////
  31. //                                                      //
  32. //                  C++ing How Series                   //
  33. //                                                      //
  34. //////////////////////////////////////////////////////////
  35.  
  36. #include "DL_3.Hpp"
  37.  
  38. //////////////////////////////////////////////////////////
  39. //                    Cmp_FileName()                    //
  40. //                                                      //
  41. //       Compares two filenames together for the qsort  //
  42. //       If a numerical filename is passed it is con-   //
  43. //       verted to an integer value for processing.     //
  44. //////////////////////////////////////////////////////////
  45.  
  46. static int Cmp_FileName(const FIND **p1, const FIND **p2)
  47. {
  48.        int  k1 = atoi((*p1)->name),
  49.             k2 = atoi((*p2)->name);
  50.  
  51.        if (k1 && k2)
  52.               return (k1 - k2);
  53.  
  54.        return strcmp((*p1)->name, (*p2)->name);
  55. }
  56.  
  57. //////////////////////////////////////////////////////////
  58. //                     Cmp_FileExt()                    //
  59. //                                                      //
  60. //      Compares two file extensions together for       //
  61. //      the qsort.  If they match then the filename     //
  62. //      is used instead.                                //
  63. //////////////////////////////////////////////////////////
  64.  
  65. inline int Cmp_FileExt(const FIND **p1, const FIND **p2)
  66. {
  67.  
  68.        int i = strcmp(strchr((*p1)->name,'.')+one,
  69.                       strchr((*p2)->name,'.')+one);
  70.  
  71.        if (i)
  72.               return (i);
  73.  
  74.        Cmp_FileName(p1,p2);
  75. }
  76.  
  77. //////////////////////////////////////////////////////////
  78. //                    Cmp_FileDate()                    //
  79. //                                                      //
  80. //      Compares two file dates together for the        //
  81. //      qsort.  If they match then the file times       //
  82. //      are used instead.                               //
  83. //////////////////////////////////////////////////////////
  84.  
  85. inline int Cmp_FileDate(const FIND **p1, const FIND **p2)
  86. {
  87.        int i = (*p1)->date - (*p2)->date;
  88.  
  89.        if (i)
  90.               return (i);
  91.  
  92.        if ((*p1)->time > (*p2)->time)
  93.               return one;
  94.  
  95.        if ((*p1)->time < (*p2)->time)
  96.               return minusone;
  97.  
  98.        Cmp_FileName(p1,p2);
  99. }
  100.  
  101. //////////////////////////////////////////////////////////
  102. //                    Cmp_FileSize()                    //
  103. //                                                      //
  104. //      Compares two file sizes together for the        //
  105. //      qsort.  If they match the file names are        //
  106. //      used instead.                                   //
  107. //////////////////////////////////////////////////////////
  108.  
  109. inline int Cmp_FileSize(const FIND **p1, const FIND **p2)
  110. {
  111.        if ((*p1)->size > (*p2)->size)
  112.               return one;
  113.  
  114.        if ((*p1)->size < (*p2)->size)
  115.               return minusone;
  116.  
  117.        Cmp_FileName(p1,p2);
  118. }
  119.  
  120. //////////////////////////////////////////////////////////
  121. //                                                      //
  122. //            Class FileList::FileList()                //
  123. //                                                      //
  124. //      Constructor                                     //
  125. //                                                      //
  126. //      Stores the specified disk directory struct-     //
  127. //      ures in dynamic memory accessed via an ar-      //
  128. //      ray of pointers also allocated.  Assigns a      //
  129. //      pointer to the structure pointer array and      //
  130. //      reallocates to the number of returned files.    //
  131. //                                                      //
  132. //      char *name - Drive\Path\Pattern                 //
  133. //                                                      //
  134. //      int attrib - File attributes to search for      //
  135. //                                                      //
  136. //////////////////////////////////////////////////////////
  137.  
  138. static
  139. FileList::FileList(const char* name,const int attrib)
  140. {
  141.      FIND dta;
  142.      union REGS inregs, outregs;
  143.  
  144.  
  145.      num_files = zero;
  146.      match_numbers_allocated = zero;
  147.  
  148.      bdos(0x1A,&dta);
  149.  
  150.      inregs.x.ax = 0x4E00;
  151.      inregs.x.dx = (int) name;
  152.      inregs.x.cx = attrib;
  153.      intdos(&inregs,&outregs);
  154.  
  155.      if (outregs.x.cflag) {
  156.           num_files = error;
  157.           return;
  158.      }
  159.  
  160.      F = (FIND **)new FIND *[MAXFILES];
  161.  
  162.      if (!F) {
  163.           cerr << "Error: F array not allocated!\n";
  164.           exit(error);
  165.      }
  166.  
  167.      for (int i = zero; !outregs.x.cflag && (i < MAXFILES); i++) {
  168.           num_files++;
  169.           F[i] = (FIND *)new FIND;
  170.  
  171.           if (F[i])
  172.                *F[i] = dta;
  173.           else {
  174.                cerr << "Error: F[i] structure not",
  175.                     "allocated!\n";
  176.                exit(error);
  177.           }
  178.  
  179.           inregs.x.ax= 0x4F00;
  180.           intdos(&inregs,&outregs);
  181.      }
  182.  
  183.      F = realloc(F,num_files*sizeof(FIND *));
  184. }
  185.  
  186. //////////////////////////////////////////////////////////
  187. //                                                      //
  188. //             Class FileList::~FileList()              //
  189. //                                                      //
  190. //       Destructor for Class FileList.                 //
  191. //                                                      //
  192. //////////////////////////////////////////////////////////
  193.  
  194. FileList::~FileList()
  195. {
  196.      for (; zero < num_files--;)
  197.           delete F[num_files];
  198.  
  199.      delete F;
  200.  
  201.      if (match_numbers_allocated)
  202.           delete match_numbers;
  203. }
  204.  
  205. //////////////////////////////////////////////////////////
  206. //                                                      //
  207. //          Class FileList::FileName_Match()            //
  208. //                                                      //
  209. //       Returns an array of integers that indicate     //
  210. //       the relative offset of each matching file-     //
  211. //       name.ext within the directory structures.      //
  212. //                                                      //
  213. //////////////////////////////////////////////////////////
  214.  
  215. static int *
  216. FileList::FileName_Match(char *string) const
  217. {
  218.      int *num;
  219.  
  220.      match_numbers = num = new int[num_files];
  221.  
  222.      if (!match_numbers) {
  223.           cerr << "Error: `num' array not allocated!\n";
  224.           return NULL;
  225.      } else {
  226.           match_numbers_allocated = true;
  227.      }
  228.  
  229.      int i = num_files;
  230.      strupr(string);
  231.      do {
  232.           if(strstr(F[i]->name,string))
  233.                *(num++) = i;
  234.      } while (i--);
  235.      *num++ = zero;
  236.  
  237.      match_numbers = realloc(match_numbers,
  238.                             (num - match_numbers) << one);
  239.  
  240.      return match_numbers;
  241. }
  242. //////////////////////////////////////////////////////////
  243. //                                                      //
  244. //                Class FileList::Print()               //
  245. //                                                      //
  246. //       Prints a formated display of the directory     //
  247. //       structures.                                    //
  248. //                                                      //
  249. //////////////////////////////////////////////////////////
  250.  
  251. static void
  252. FileList::Print() const
  253. {
  254.        int    m,
  255.               h;
  256.  
  257.        for (int i = zero; i < num_files; i++) {
  258.               cout << F[i]->name << "\t";
  259.  
  260.               if (strlen(F[i]->name) < eight)
  261.                      cout << "\t";
  262.  
  263.               cout << form("%9lu",F[i]->size) << " ";
  264.  
  265.               cout << form("%02d",
  266.                           ((F[i]->date >> five) & 0x0F))
  267.                    << "/"
  268.                    << form("%02d",(F[i]->date & 0x001F))
  269.                    << "/"
  270.                    << form("%02d",(((F[i]->date >> nine)
  271.                                   & 0x7F) | 80));
  272.  
  273.               m = (F[i]->time >> five) & 0x3F;
  274.               h = (F[i]->time >> eleven) & 0x1F;
  275.               cout << " " << form("%2d",h)
  276.                    << ":"
  277.                    << form("%02d",m);
  278.  
  279.               if (h > 12)
  280.                      cout << " pm";
  281.               else
  282.                      cout << " am";
  283.  
  284.               cout << "\n";
  285.        }
  286. }
  287.  
  288. //////////////////////////////////////////////////////////
  289. //                                                      //
  290. //            Class FileName::FileName()                //
  291. //                           :FileList()                //
  292. //                                                      //
  293. //      Constructor                                     //
  294. //                                                      //
  295. //      Creates an instance of FileList via its con-    //
  296. //      structor then sorts the directory structures    //
  297. //      in ascending order according to File Names.     //
  298. //                                                      //
  299. //////////////////////////////////////////////////////////
  300.  
  301. inline FileName::FileName(const char *name,const int attrib)
  302.                 :FileList(name,attrib)
  303. {
  304.      qsort(F, num_files, sizeof(FIND *), Cmp_FileName);
  305. }
  306.  
  307. //////////////////////////////////////////////////////////
  308. //                                                      //
  309. //            Class FileSize::FileSize()                //
  310. //                           :FileList()                //
  311. //                                                      //
  312. //      Constructor                                     //
  313. //                                                      //
  314. //      Creates an instance of FileList via its con-    //
  315. //      structor then sorts the directory structures    //
  316. //      in ascending order according to File Sizes.     //
  317. //                                                      //
  318. //////////////////////////////////////////////////////////
  319.  
  320. inline FileSize::FileSize(const char *name,const int attrib)
  321.                 :FileList(name,attrib)
  322. {
  323.      qsort(F, num_files, sizeof(FIND *), Cmp_FileSize);
  324. }
  325.  
  326. //////////////////////////////////////////////////////////
  327. //                                                      //
  328. //            Class FileDate::FileDate()                //
  329. //                           :FileList()                //
  330. //                                                      //
  331. //      Constructor                                     //
  332. //                                                      //
  333. //      Creates an instance of FileList via its con-    //
  334. //      structor then sorts the directory structures    //
  335. //      in ascending order according to File Dates.     //
  336. //                                                      //
  337. //////////////////////////////////////////////////////////
  338.  
  339. inline FileDate::FileDate(const char *name,const int attrib)
  340.                 :FileList(name,attrib)
  341. {
  342.      qsort(F, num_files, sizeof(FIND *), Cmp_FileDate);
  343. }
  344.  
  345. //////////////////////////////////////////////////////////
  346. //                                                      //
  347. //            Class FileExt::FileExt()                  //
  348. //                          :FileList()                 //
  349. //                                                      //
  350. //      Constructor                                     //
  351. //                                                      //
  352. //      Creates an instance of FileList via its con-    //
  353. //      structor then sorts the directory structures    //
  354. //      in ascending order according to File Ext's.     //
  355. //                                                      //
  356. //////////////////////////////////////////////////////////
  357.  
  358. inline FileExt::FileExt(const char *name,const int attrib)
  359.                :FileList(name,attrib)
  360. {
  361.      qsort(F, num_files, sizeof(FIND *), Cmp_FileExt);
  362. }
  363.  
  364.  
  365. //////////////////////////////////////////////////////////
  366. //                                                      //
  367. //      First_Object() creates a FileList object        //
  368. //      that is not sorted, the default.  Implemented   //
  369. //      as a seperate function allowing the destructor  //
  370. //      to be called.                                   //
  371. //                                                      //
  372. //////////////////////////////////////////////////////////
  373.  
  374. inline void
  375. First_Object()
  376. {
  377.        FileList test1;
  378.  
  379.        if (test1.Number() != error)
  380.               test1.Print();
  381.        else
  382.               cerr << "\tNo files to print.\n";
  383.        cout << "\n";
  384. }
  385.  
  386. //////////////////////////////////////////////////////////
  387. //                                                      //
  388. //      Second_Object() creates a FileName object       //
  389. //      that is sorted by the file name.  Implemented   //
  390. //      as a seperate function allowing the destructor  //
  391. //      to be called.                                   //
  392. //                                                      //
  393. //////////////////////////////////////////////////////////
  394.  
  395. inline void
  396. Second_Object()
  397. {
  398.        FileName test2;
  399.  
  400.        if (test2.Number() != error)
  401.               test2.Print();
  402.        else
  403.               cerr << "\tNo files to print\n";
  404.        cout << "\n";
  405. }
  406.  
  407. //////////////////////////////////////////////////////////
  408. //                                                      //
  409. //      Third_Object() creates a FileExt object         //
  410. //      that is sorted by the file extension.           //
  411. //      Implemented as a seperate function allowing     //
  412. //      the destructor to be called.                    //
  413. //                                                      //
  414. //////////////////////////////////////////////////////////
  415.  
  416. inline void
  417. Third_Object()
  418. {
  419.        FileExt test3;
  420.  
  421.        if (test3.Number() != error)
  422.               test3.Print();
  423.        else
  424.               cerr << "\tNo files to print\n";
  425.        cout << "\n";
  426. }
  427.  
  428. //////////////////////////////////////////////////////////
  429. //                                                      //
  430. //      Fourth_Object() creates a FileDate object       //
  431. //      that is sorted by the file date and time.       //
  432. //      Implemented as a seperate function allowing     //
  433. //      the destructor to be called.                    //
  434. //                                                      //
  435. //////////////////////////////////////////////////////////
  436.  
  437. inline void
  438. Fourth_Object()
  439. {
  440.        FileDate test4;
  441.  
  442.        if (test4.Number() != error)
  443.               test4.Print();
  444.        else
  445.               cerr << "\tNo files to print\n";
  446.        cout << "\n";
  447.  
  448. }
  449.  
  450.  
  451. //////////////////////////////////////////////////////////
  452. //                                                      //
  453. //      Main() tests FileList  FileName  FileExt        //
  454. //                   FileDate  FileSize                 //
  455. //                                                      //
  456. //////////////////////////////////////////////////////////
  457.  
  458. main()
  459. {
  460. //
  461. // Test the sorting methods
  462. //
  463.  
  464.      First_Object();
  465.      Second_Object();
  466.      Third_Object();
  467.      Fourth_Object();
  468.  
  469.      FileSize test5("*.*",FA_DIREC | FA_HIDDEN);
  470.  
  471.      if (test5.Number() != error)
  472.           test5.Print();
  473.      else
  474.           cerr << "\tNo files to print\n";
  475.      cout << "\n";
  476.  
  477. //
  478. // Test the FileName_Match member
  479. //
  480.  
  481.      cout << "Testing FileSize::FileName_Match()"
  482.           << " for \"com\".\n\n";
  483.      FIND test; 
  484.      int *i = test5.FileName_Match("com");
  485.      while (*i) {
  486.           test = test5.Element(*i);
  487.           int j = *i++;
  488.           cout << "test5 file " << ++j << " is: "
  489.                << test.name << "\n";
  490.      };
  491.  
  492. //
  493. // Test the Element and Number members
  494. //
  495.  
  496.      test = test5.Element(two);
  497.      cout << "\nThird element of test5 is: " << test.name
  498.           << "\n\nTotal number of files = "
  499.           << test5.Number() << "\n\n";
  500.  
  501.      cout << "\nFinished\n";
  502.  
  503.      exit(zero);
  504. }
  505.  
  506.